package tests;

import global.*;
import heap.*;
import iterator.*;
import iterator.Iterator;

import java.io.*;
import java.util.*;

import columnar.ColumnarFile;
import diskmgr.PCounter;

public class colsort implements GlobalConst {

	public String datafilename, cdbname, filename;
	private static short REC_LEN1 = 32; 
	private static int   SORTPGNUM = 12;
	public int numcolumns;
	public TID[] tidArr;
	ColumnarFile _cf;
	//int[] colnosg;
	int[] attrtypesg;
	int[] target_colnums;
	int[] target_attr;
	int sortcolumn = -1;
	int numbuf = 50;

	public colsort() 
	{
	}

	public void sortMethod(String cdbname, String Colfilename,String cname,
			String[] targetcolname, String operator, String value, int numbuf, String sortcol) throws IOException
	{	  
	try
	{
			String dbpath = cdbname;
			String record;

			int  targetnum, nocol;
			Scanner sc = new Scanner(System.in);
			SystemDefs sysdef = new SystemDefs(dbpath, 0, numbuf, "Clock");

			PCounter.initialize();
			this.filename = Colfilename;
			int i = 0, z = 0;
		
			BufferedReader br = new BufferedReader(new FileReader("/tmp/"+Colfilename+".hdr"));

			while ((record = br.readLine()) != null) {
				z++;
			}
			this.numcolumns = z;
			int[] colnos = new int[this.numcolumns];
			int[] attrtypes = new int[this.numcolumns];
		// all colnames, colnumbers and attr by parsing the name.hdr
			String[] colnames = new String[this.numcolumns];
		
			int condn_columnno = -1, condn_attrType = -1;
			String condn_columnname = " ";
		// target column number and attr
			
			// read from name.hdr
			BufferedReader br4 = new BufferedReader(new FileReader("/tmp/"+Colfilename+".hdr"));
			while ((record = br4.readLine()) != null) {
			StringTokenizer st4 = new StringTokenizer(record, "\t");
			while (st4.hasMoreTokens()) {
				StringTokenizer st5 = new StringTokenizer(st4.nextToken(), " ");
				String colName = st5.nextToken().trim();
				colnames[i] = colName;
				int colNum = Integer.parseInt(st5.nextToken().trim());
				colnos[i] = colNum;
				int attrType = Integer.parseInt(st5.nextToken().trim());
				attrtypes[i] = attrType;
				if (colName.equals(cname))
				{
					condn_columnno = colNum;
					condn_attrType = attrType;
					condn_columnname = colName;
				}
				if ((colName.equals(sortcol)) && (!sortcol.equals("XYZ")))
				{
					sortcolumn = colNum;
				}
			}
			i++;

		}
		int sort_fldlen ;
		if (attrtypes[sortcolumn-1]==0)
		{
			sort_fldlen = strlen;
		}
		else
		{
			sort_fldlen = 4;
		}	
		target_colnums= new int[targetcolname.length];
		target_attr= new int[targetcolname.length];
		int ch=0; 
//			for(int p=0;p<targetcolname.length;p++)
//				if(targetcolname[p]==)
		for (int p=0;p<targetcolname.length;p++)
		{
		  for(int k=0;k<numcolumns;k++)
		  { 
			if(targetcolname[p].equals(colnames[k]))
			{
			   	target_attr[p]= attrtypes[k];
			   	target_colnums[p]=k+1;
			   	ch++;    	
			}
		  }
		}
		if(ch!=targetcolname.length)
		{
			System.out.println("invalid Colname"+ch);
			System.exit(0);
		}		

		System.out.println("Columnar Sort");
		
		// conditional expression
		CondExpr[] outFilter = new CondExpr[2];
		outFilter[0] = new CondExpr();
		outFilter[0].op = new AttrOperator(AttrOperator.aopEQ);
		outFilter[0].next = null;
		outFilter[0].type1 = new AttrType(AttrType.attrSymbol);
		if (condn_attrType == 1)
			outFilter[0].type2 = new AttrType(AttrType.attrInteger);
		else
			outFilter[0].type2 = new AttrType(AttrType.attrString);
		outFilter[0].operand1.symbol = new FldSpec(new RelSpec(RelSpec.outer), 1);
		if (condn_attrType == 1)
			outFilter[0].operand2.integer = Integer.parseInt(value); 
		else
			outFilter[0].operand2.string = value; 
		outFilter[1] = null;


		Tuple t = new Tuple();
		AttrType[] Stypes = new AttrType[1]; // one attribute
		AttrType[] Fstypes = new AttrType[this.numcolumns];
		short[] Msizes = new short[1];
		if (condn_attrType == 1)
			Stypes[0] = new AttrType(AttrType.attrInteger);
		else
		{
			Stypes[0] = new AttrType(AttrType.attrString);
			Msizes[0] = strlen;
		}
		int k = 0;
		for (int cou = 0; cou < numcolumns; cou++) {
			if (attrtypes[cou] == 0) {
				Fstypes[cou] = new AttrType(AttrType.attrString);
				k++;
			} else
				Fstypes[cou] = new AttrType(AttrType.attrInteger);
		}
		short[] Ssizes = new short[k];
		for(i = 0; i <k; i++)
		{
			Ssizes[i] = strlen;
		}
		FldSpec[] Sprojection = new FldSpec[1];
		// find what fields are required and construct corresponding
		// projection
		Sprojection[0] = new FldSpec(new RelSpec(RelSpec.outer), 1); // order
																		// of
																		// fields
		short numfields_input = 1; // no. of fields in input tuple
		short numfields_output = 1; // no. of fields in output - take from
									// target column names
		TupleOrder[] order = new TupleOrder[1];
	    order[0] = new TupleOrder(TupleOrder.Ascending);
	    //order[1] = new TupleOrder(TupleOrder.Descending);
		
	    ColumnarFileScan cfs = null;
		String columnarfilename_attribute = this.filename
		+ (condn_columnno - 1);// / construct the file name
								// based on column no.
	    try {
					cfs = new ColumnarFileScan(columnarfilename_attribute, Stypes,
					Msizes, numfields_input, numfields_output, Sprojection,
					outFilter, attrtypesg);
		}
		catch (Exception e) {
			System.err.println("" + e);
		}  	 
//		public ColumnarSort(AttrType[] in,short len_in, short[] str_sizes, String ColumnarFileName,	int sort_fld,
//				TupleOrder sort_order,	int sort_fld_len,int n_pages, Iterator fs )
		ColumnarSort cs;
		try
		{
			cs = new ColumnarSort(Fstypes,(short)Fstypes.length, Ssizes, columnarfilename_attribute,sortcolumn,
				order[0],sort_fldlen,SORTPGNUM, cfs);
			try {
				while ((t = cs.get_next()) != null) {

					t.print(Fstypes);
				}
			} catch (Exception e) {
				System.err.println("" + e);
				e.printStackTrace();
			}
			cs.close();
		
		}
		catch (Exception e) {
			System.err.println("" + e);
		}
		}
		catch (Exception e) {
			System.out.println(e.getMessage());
		}
		finally
		{
			try {
				// IntegerValue vc = new IntegerValue(new Integer(1));
				// cf.createBitMapIndex(2, (ValueClass)vc);
				// for(i=0;i<this.tidArr.length;i++)
				// cf.getTuple(this.tidArr[i]);
				// cf.markTupleDeleted(tid);
				// cf.purgeAllDeletedTuples();
				SystemDefs.JavabaseBM.unpinAllPages();
				SystemDefs.JavabaseBM.flushAllPages();
				System.out.println("Number of Pages Read: " + PCounter.rcounter);
				System.out.println("Number of Pages Written: "
						+ PCounter.wcounter);
			} 
			catch (Exception e) 
			{
			}
		}
		}
	public static void main(String args[]) throws IOException, HFException,
	HFBufMgrException, HFDiskMgrException {
		String cdbname = "/tmp/cdbname";
		colsort cs1 = new colsort();
		
		//String[] target = new String[4];
		Scanner sc= new Scanner(System.in);
		System.out.println("Enter the target columns in the format colname1:colname2:..");
		String  token=sc.next();
		String delims = "[:]+";
		String sortcol = "XYZ";
		String[] target = token.split(delims);  

		System.out.println("lenght"+target.length);
   
 
	    System.out.println("Enter the constraint column name");
        String col = sc.next();
	    System.out.println("Enter the constraint column value");
	    String value = sc.next();
	    System.out.println("Enter the buffer pool size");
		int numbuf = sc.nextInt();
		System.out.println("Do you want the result sorted? y/n");
		String st = sc.next();
		if (st.equalsIgnoreCase("y"))
		{
		   System.out.println("Enter Column to be sorted");
		   sortcol = sc.next();
		}
		   
   // sc1.runTest1(cdbname,"hpfile", col, target, "=", value, access,numbuf, sortcol);

//	qu.runTest1(cdbname,"hpfile", "A", target, "=", "West_Virginia", "filescan");
	cs1.sortMethod(cdbname, "hpfile", "A", target, "=", "Connecticut", numbuf, sortcol);
				

	}
}